;(function(root) {
  function isFile(node) {
    return node instanceof File;
  }

  function objectToFormData(obj, form, namespace) {
    var fd = form || {};
    var formKey;

    for (var property in obj) {
      if (!Object.prototype.hasOwnProperty.call(obj, property)) {
        continue
      }
      var key = Array.isArray(obj) ? '[]' : `[${property}]`;
      var node = obj[property];

      if (namespace) {
        formKey = namespace + key;
      }
      else {
        formKey = property;
      }
      if (node && typeof node === 'object' && isFile(node)) {
        fd[formKey] = node
      }
      // if the property is an object, but not a File, use recursivity.
      else if (node && typeof obj[property] === 'object') {
        objectToFormData(obj[property], fd, formKey);
      }
      else {
        fd[formKey] = node;
      }
    }
    return fd;
  }

  var TYPES = {
    0: 'text/plain',
    1: 'application/json',
    2: 'application/x-www-form-urlencoded',
    3: 'multipart/form-data'
  };

  var requestURL = document.currentScript.src.replace(SDK_URI, REQUEST_URI);

  function createRequest(contentType) {
    var config = {
      url: requestURL,
      type: contentType,
      fetch: function(url, options) {
        return fetch(url, options).then(function(res) {
          return res.json();
        });
      }
    };

    return {
      config: function(options) {
        Object.assign(config, options);
        return this;
      },
      run: function(program, params, dataList) {
        var code = program.trim()
          .replace(/{(\w+)}/g, function(matched, key) {
            if (params && params[key]) {
              return params[key];
            }
            return matched;
          })
          .split('\n')
          .map(function(line) {
            var text = line.trim();
            if (/^\/\//.test(text)) {
              return ''
            }
            var end = text[text.length - 1];
            if (end === ';' || end === ',') {
              return text;
            }
            else if (['{', '}', '[', ']', '<', '>'].indexOf(end) > -1) {
              return text;
            }
            else {
              return text + ',';
            }
          })
          .join('')
          .replace(/,([}\]>])/, '$1')
          .replace(/\s+/g, ' ');

        var options = {
          method: 'POST',
          headers: {
            'accept-type': 'application/json',
          },
        };

        if (dataList) {
          var data = { _: code };
          dataList.forEach((item, i) => {
            data[i] = item;
          });
          if (config.type === TYPES[3] || config.type === 3) {
            const flatdata = objectToFormData(data);
            const formdata = new FormData();
            Object.keys(flatdata).forEach((key) => {
              const value = flatdata[key];
              if (isFile(value)) {
                formdata.append(key, value, value.name);
              }
              else {
                formdata.append(key, value);
              }
            });
            options.body = formdata;
          }
          else if (config.type === TYPES[2] || config.type === 2) {
            const flatdata = objectToFormData(data);
            options.body = new URLSearchParams(flatdata);
            options.headers['content-type'] = TYPES[2];
          }
          else {
            options.body = JSON.stringify(data);
            options.headers['content-type'] = TYPES[1];
          }
        }
        else {
          options.body = code;
        }

        return config.fetch(config.url, options);
      }
    };
  }

  var ScopedRequest = createRequest();
  ScopedRequest.createRequest = createRequest;
  root.ScopedRequest = ScopedRequest;
} (typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof self !== 'undefined' ? self : this));
